package library

///
// 数据转换库
///
import (
	"bytes"
	"encoding/binary"
)

// Transform 数据转换类
type Transform struct {
	Data  *bytes.Buffer
	Order binary.ByteOrder
}

// Init 初始化
func (T *Transform) Init() {
	T.Data = bytes.NewBuffer([]byte{})
	T.Order = binary.BigEndian
}

// Add 添加数据
func (T *Transform) Add(value interface{}) {
	switch V := value.(type) {
	case
		bool, int8, uint8, int16, uint16, int32, uint32, int64, uint64,
		*bool, *int8, *uint8, *int16, *uint16, *int32, *uint32, *int64, *uint64:
		binary.Write(T.Data, T.Order, value)
	case []bool, []int8, []uint8, []int16, []uint16, []int32, []uint32, []int64, []uint64:
		T.Add(T.ArrayLen(V))
		binary.Write(T.Data, T.Order, value)
	case int:
		binary.Write(T.Data, T.Order, int32(V))
	case *int:
		binary.Write(T.Data, T.Order, int32(*V))
	case string:
		T.Add([]byte(V))
	case *string:
		T.Add([]byte(*V))
	}
}

// GetBool 取出 Bool 类型数据
func (T *Transform) GetBool() (value bool) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetInt8 取出 Int8 类型数据
func (T *Transform) GetInt8() (value int8) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetUint8 取出 Uint8 类型数据
func (T *Transform) GetUint8() (value uint8) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetInt16 取出 Int16 类型数据
func (T *Transform) GetInt16() (value int16) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetUint16 取出 Uint16 类型数据
func (T *Transform) GetUint16() (value uint16) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetInt32 取出 Int32 类型数据
func (T *Transform) GetInt32() (value int32) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetUint32 取出 Uint32 类型数据
func (T *Transform) GetUint32() (value uint32) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetInt64 取出 Int64 类型数据
func (T *Transform) GetInt64() (value int64) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetUint64 取出 Uint64 类型数据
func (T *Transform) GetUint64() (value uint64) {
	binary.Read(T.Data, T.Order, &value)
	return
}

// GetString 取出 String 类型数据
func (T *Transform) GetString() string {
	n := int(T.GetInt32())
	return string(T.Data.Next(n))
}

// GetArray 取出数组数据
func (T *Transform) GetArray(V interface{}) (value interface{}) {
	switch V.(type) {
	case []bool, []int8, []uint8, []int16, []uint16, []int32, []uint32, []int64, []uint64:
		// 类型
		n := int(T.GetInt32())
		// 初始化
		switch V.(type) {
		case []bool:
			value = make([]bool, n)
		case []int8:
			value = make([]int8, n)
		case []uint8:
			value = make([]uint8, n)
		case []int16:
			value = make([]int16, n)
		case []uint16:
			value = make([]uint16, n)
		case []int32:
			value = make([]int32, n)
		case []uint32:
			value = make([]uint32, n)
		case []int64:
			value = make([]int64, n)
		case []uint64:
			value = make([]uint64, n)
		}
		// 转换
		binary.Read(T.Data, T.Order, value)
	}
	return
}

// ArrayLen 数组数量
func (T *Transform) ArrayLen(value interface{}) int {
	switch V := value.(type) {
	case []bool:
		return len(V)
	case []int8:
		return len(V)
	case []uint8:
		return len(V)
	case []int16:
		return len(V)
	case []uint16:
		return len(V)
	case []int32:
		return len(V)
	case []uint32:
		return len(V)
	case []int64:
		return len(V)
	case []uint64:
		return len(V)
	}
	return 0
}
